/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jxta;


import atributos.Atributo;
import com.sun.istack.internal.FinalArrayList;
import exclusionmutua.TokenListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.jxta.document.MimeMediaType;
import net.jxta.endpoint.Message;
import net.jxta.endpoint.Message.ElementIterator;
import net.jxta.endpoint.MessageElement;
import net.jxta.endpoint.WireFormatMessage;
import net.jxta.endpoint.WireFormatMessageFactory;
import net.jxta.pipe.InputPipe;

import net.jxta.pipe.PipeMsgEvent;
import net.jxta.pipe.PipeMsgListener;
import net.jxta.pipe.PipeService;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.util.CountingOutputStream;
import net.jxta.util.DevNullOutputStream;
import utilidades.AdminMensaje;

/**
 *
 * @author kastillo
 */
public class CrearInputPipe implements Runnable, PipeMsgListener {

    private PipeService pipeService;
    private PipeAdvertisement pipeAdv;
    private InputPipe inputPipe = null;
    private PipeMsgListener pipeMsgListener = this;

    private static ArrayList<Atributo> atributos;
    public static PipeAdvertisement pipeAdvRemoto;
    private static ArrayList<Atributo> resultados;
    public static ArrayList<Atributo> resultadosEstados;
    public static Map<PipeAdvertisement, List<Atributo>> resultadosMap =
            new HashMap<PipeAdvertisement, List<Atributo>>();

    public CrearInputPipe(PipeService pipeService, PipeAdvertisement pipeAdv) {
        this.pipeService =pipeService;
        this.pipeAdv = pipeAdv;
    }

    public CrearInputPipe(PipeService pipeService,
            PipeAdvertisement pipeAdv,
            PipeMsgListener pipeMsgListener) {
        this.pipeService = pipeService;
        this.pipeAdv = pipeAdv;
        this.pipeMsgListener = pipeMsgListener;
    }
    
    public void run() {

        try {
            System.out.println("Creating input pipe");
            // Create the InputPipe and register this for message arrival
            // notification call-back
            inputPipe = pipeService.createInputPipe(pipeAdv, pipeMsgListener);
            atributos =null;
            resultados = new ArrayList<Atributo>();
            resultadosEstados = new ArrayList<Atributo>();
        } catch (IOException io) {
            io.printStackTrace();
            return;
        }
        if (inputPipe == null) {
            System.out.println(" cannot open InputPipe");
            System.exit(-1);
        }
        System.out.println("Waiting for msgs on input pipe");
      

    }

    public void pipeMsgEvent(PipeMsgEvent event) {

        Message msg;
        try {
            // Obtain the message from the event


            msg = event.getMessage();
            if (msg == null) {
                System.out.println("Received an empty message");
                return;
            }



             atributos = AdminMensaje.getAtributoFromRespMsj(msg, AdminMensaje.NAME_SPACE);

             pipeAdvRemoto = AdminMensaje.getPipeFromRespMsj(msg, AdminMensaje.NAME_SPACE);
             resultadosMap.put(pipeAdvRemoto, getAtributos());

            if(ManagerJXTA.estadoGlobal.getColor().equals("ROJO"))
            {
                for(Atributo att:atributos)
                    {
                     //   if(!existeId(att.getId()))
                            resultadosEstados.add(att);
                    }
            }
           else
            {
             for(Atributo att:atributos)
             {
               if(!existeId(att.getId()))
                   resultados.add(att);
             }
            }

            // dump the message content to screen
            printMessageStats(msg, true);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
//
//        // get all the message elements
//        Message.ElementIterator en = msg.getMessageElements();
//
//        if (!en.hasNext()) {
//            return;
//        }
//
//        // get the message element in the name space PipeClient.MESSAGE_NAME_SPACE
//        MessageElement msgElement = msg.getMessageElement(null, "PipeClient.MESSAGE_NAME_SPACE");
//
//        // Get message
//        if (msgElement.toString() == null) {
//            System.out.println("null msg received");
//        } else {
//            Date date = new Date(System.currentTimeMillis());
//            System.out.println("Message received at :" + date.toString());
//            System.out.println("Message  created at :" + msgElement.toString());
//        }
    }


 public static void printMessageStats(Message msg, boolean verbose) {
        try {
            CountingOutputStream cnt;
            ElementIterator it = msg.getMessageElements();

            System.out.println("------------------Begin Message---------------------");
            WireFormatMessage serialed = WireFormatMessageFactory.toWire(msg, new MimeMediaType("application/x-jxta-msg"), null);

            System.out.println("Message Size :" + serialed.getByteLength());
            while (it.hasNext()) {
                MessageElement el = it.next();
                String eName = el.getElementName();

                cnt = new CountingOutputStream(new DevNullOutputStream());
                el.sendToStream(cnt);
                long size = cnt.getBytesWritten();

                System.out.println("Element " + eName + " : " + size);
                if (verbose) {
                    System.out.println("[" + el + "]");
                }
            }
            System.out.println("-------------------End Message----------------------");
        } catch (Exception e) {
            e.printStackTrace();

        }
    }

    /**
     * @return the atributos
     */
    public ArrayList<Atributo> getAtributos() {
        return atributos;
    }

    /**
     * @param atributos the atributos to set
     */
    public void setAtributos(ArrayList<Atributo> atributos) {
        this.atributos = atributos;
    }

    /**
     * @return the resultados
     */
    public static ArrayList<Atributo> getResultados() {
        return resultados;
    }

    /**
     * @param resultados the resultados to set
     */
    public void setResultados(ArrayList<Atributo> resultados) {
        this.resultados = resultados;
    }

    private boolean existeId(String id) {
        
        boolean existe = false;
        for (Atributo a : resultados)
        {
            if(a.getId().equals(id)){
                existe = true;
            }
        }

        return existe;
    }

}
